﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace Common.Extension
{
    /// <summary>
    /// String对象的扩展
    /// </summary>
    /// <remarks>
    /// <![CDATA[
    /// 扩展一些常用的判断、数据转换等
    /// ]]>
    /// </remarks>
    public static class StringExtension
    {
        /// <summary>
        /// 返回一个安全值转换对象
        /// </summary>
        /// <param name="value">任意对象</param>
        /// <returns></returns>
        public static StringSafeValue Safe(this string value)
        {
            return new StringSafeValue(value);
        }

        /// <summary>
        /// 是否有值:Null、Empty、英文空格视为无值
        /// </summary>
        /// <param name="value">需要判断的字符串</param>
        /// <returns>Null、Empty、空格视为false</returns>
        public static bool HasValue(this string value)
        {
            return (value + string.Empty).Trim().Length > 0;
        }

        /// <summary>
        /// 是否无值:Null、Empty、英文空格视为无值
        /// </summary>
        /// <param name="value">需要判断的字符串</param>
        /// <returns>Null、Empty、空格视为true</returns>
        public static bool Empty(this string value)
        {
            return !value.HasValue();
        }

        /// <summary>
        /// 安全的从当前 System.String 对象移除所有前导空白字符和尾部空白字符。
        /// </summary>
        /// <param name="value">System.String</param>
        /// <returns></returns>
        public static string SafeTrim(this string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return value;
            }
            return value.Trim();
        }

        /// <summary>
        /// 安全值，避免为null
        /// </summary>
        /// <param name="value">System.String</param>
        /// <returns></returns>
        public static string SafeValue(this string value)
        {
            return value + string.Empty;
        }

        /// <summary>
        /// 转换为掩码{4}****{4} 如：888888888 结果：8888****8888
        /// </summary>
        /// <param name="value">字符串</param>
        /// <returns>掩码{4}****{4} </returns>
        public static string ToMask(this string value)
        {
            return value.ToMask(4, "****", 4);

        }
        /// <summary>
        /// 转换为掩码{n}****{n}
        /// </summary>
        /// <param name="value">字符串</param>
        /// <param name="headLength">头部预留位数长度</param>
        /// <param name="replacement">中部替换字符串</param>
        /// <param name="tailLength">尾部预留位数长度</param>
        /// <example>
        /// <code>
        /// <![CDATA[
        /// void ToMaskDemo()
        /// {
        ///     string mobileNo="13428695847";
        ///     
        ///     string maskCode=mobileNo.ToMask(3,"*",4);
        ///     //maskCode值为：134****5847
        /// }
        /// ]]>
        /// </code>
        /// </example>
        /// <returns></returns>
        public static string ToMask(this string value, int headLength, string replacement, int tailLength)
        {
            if (value.Empty())
            {
                return string.Empty;
            }

            if (value.Length < headLength + tailLength + 1)
            {
                if (value.Length < headLength)
                {
                    return value;
                }
                var temp = string.Empty;
                //取出前面字符
                temp = value.Substring(0, headLength);
                //中间替换字符
                temp += replacement;
                //取出尾部字符
                if (value.Length > tailLength)
                {
                    temp += value.Substring(value.Length - tailLength - 1);
                }
                return temp;
            }
            //数字：Regex.Replace("6225333442456745", @"^(\d{4})(\d+?)(\d{4})$", "$1*****$3");
            //字母+数字：Regex.Replace("6225333442456745", @"^(\w{4})(\w+?)(\w{4})$", "$1*****$3");
            return Regex.Replace(value, @"^(.{" + headLength + @"})(.+?)(.{" + tailLength + @"})$", "$1" + replacement + "$3");

        }
    }

    /// <summary>
    /// 安全值转换
    /// </summary>
    public class StringSafeValue
    {
        /// <summary>
        /// 数值
        /// </summary>
        public string Value { get; set; }

        /// <summary>
        /// 实例化一个安全值对象
        /// </summary>
        /// <param name="value"></param>
        public StringSafeValue(string value)
        {
            Value = value + string.Empty;
        }

        /// <summary>
        /// 转换为ToInt16
        /// </summary>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public short ToInt16(short defaultValue = 0)
        {
            try
            {
                if (!Value.HasValue())
                {
                    return defaultValue;
                }
                return Convert.ToInt16(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为ToInt32
        /// </summary>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public int ToInt32(int defaultValue = 0)
        {
            try
            {
                if (!Value.HasValue())
                {
                    return defaultValue;
                }
                return Convert.ToInt32(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为ToInt64
        /// </summary>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public long ToInt64(long defaultValue = 0)
        {
            try
            {
                if (!Value.HasValue())
                {
                    return defaultValue;
                }
                return Convert.ToInt64(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为可空的ToInt32
        /// </summary>
        /// <returns></returns>
        public int? ToNullableInt32(int? defaultValue = null)
        {
            try
            {
                if (!Value.HasValue())
                {
                    return defaultValue;
                }
                return Convert.ToInt32(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为decimal
        /// </summary>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public decimal ToDecimal(decimal defaultValue = 0)
        {
            try
            {
                if (!Value.HasValue())
                {
                    return defaultValue;
                }
                return Convert.ToDecimal(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为可空decimal
        /// </summary>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public decimal? ToNullableDecimal(decimal? defaultValue = null)
        {
            try
            {
                if (!Value.HasValue())
                {
                    return defaultValue;
                }
                return Convert.ToDecimal(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为string类型
        /// </summary>
        /// <param name="format">数据格式</param>
        /// <returns></returns>
        public string ToString(string format = "")
        {
            string result = string.Empty;
            try
            {
                if (!Value.HasValue())
                {
                    return result;
                }
                if (format == "")
                {
                    result = Value;
                }
                else
                {
                    result = string.Format("{0:" + format + "}", Value);
                }
                return result;
            }
            catch (Exception)
            {
                return result;
            }
        }

        /// <summary>
        /// 转换为bool类型
        /// </summary>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public bool ToBoolean(bool defaultValue = false)
        {
            try
            {
                if (!Value.HasValue())
                {
                    return defaultValue;
                }
                return Convert.ToBoolean(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为可空DateTime类型
        /// </summary>
        /// <returns></returns>
        public DateTime? ToNullableDateTime()
        {
            try
            {
                if (!Value.HasValue())
                {
                    return null;
                }
                return Convert.ToDateTime(Value);
            }
            catch (Exception)
            {
                return null;
            }
        }
        /// <summary>
        /// 转换为DateTime类型
        /// </summary>
        /// <returns></returns>
        public DateTime ToDateTime()
        {
            return ToDateTime(DateTime.MinValue);
        }

        /// <summary>
        /// 转换为DateTime类型
        /// </summary>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public DateTime ToDateTime(DateTime defaultValue)
        {
            try
            {
                if (!Value.HasValue())
                {
                    return defaultValue;
                }
                return Convert.ToDateTime(Value);
            }
            catch (Exception)
            {
                return defaultValue;
            }
        }
    }
}
